//
//  LocationManagement.m
//  GainProfit
//
//  Created by Sky-TechLab on 11/4/13.
//  Copyright (c) 2013 Jason.wu. All rights reserved.
//

#import "LocationManagement.h"

@implementation LocationManagement

__strong static LocationManagement *singleton = nil;
static int count = 0;
@synthesize address;
@synthesize city;

+ (LocationManagement *)sharedInstance
{
    // dispatch_once不仅意味着代码仅会被运行一次，而且还是线程安全的
    static dispatch_once_t pred = 0;
    dispatch_once(&pred, ^{
        singleton = [[self alloc] init];
        //[singleton startGPS];
        
    });
    return singleton;
}

+ (id)allocWithZone:(NSZone *)zone
{
    @synchronized(self)
    {
        if (!singleton && !count)
        {
            count++;
            singleton = [super allocWithZone:zone];
            return singleton;
        }
    }
    
    return nil;
}

- (void)startGPS
{
    /*GPS config*/
    _geocoder = [[CLGeocoder alloc] init];
    
    _locationManager = [[CLLocationManager alloc] init] ;
    _locService = [[BMKLocationService alloc]init];
    
    _locationManager.delegate = self;
    _locationManager.desiredAccuracy = kCLLocationAccuracyKilometer;
    _locationManager.distanceFilter = 5000.0f;
    //[_locationManager startUpdatingLocation];
    
    _mapView = [[BMKMapView alloc]init];
    _geocodesearch = [[BMKGeoCodeSearch alloc]init];
    _mapView.delegate = self; // 此处记得不用的时候需要置nil，否则影响内存的释放
    _geocodesearch.delegate = self; // 此处记得不用的时候需要置nil，否则影响内存的释放
    _locService.delegate = self;
    
    city = @"";
    [self startUpdatingLocation];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(postUpdateLocationMessage) name:@"postUpdateLocationMessage" object:nil];
}

- (void) startUpdatingLocation
{
    //[_locationManager startUpdatingLocation];
    [_locService startUserLocationService];
}

- (void)stopGPS
{
    //[_locationManager stopUpdatingLocation];
    [_locService stopUserLocationService];
//    _geocodesearch.delegate = nil; // 不用时，置nil
//    _geocodesearch = nil;
//    _mapView.delegate = nil; // 不用时，置nil
//    _mapView = nil;
}

#pragma GPS Methods
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
    [_geocoder reverseGeocodeLocation:newLocation completionHandler:^(NSArray *placemarks, NSError *error) {
        if (error)
        {
            //[self alertsInfoAction:[NSString stringWithFormat:@"Reverse Geocode Location fail: %@ Please check your network and location service.",[error localizedDescription]]];
            return;
        }
        self.placemark = [placemarks objectAtIndex:0];
        self.location = newLocation;
        //[_locationManager stopUpdatingLocation];
        NSString *strLat = [NSString stringWithFormat:@"%f", self.location.coordinate.latitude];
        NSString *strLon = [NSString stringWithFormat:@"%f", self.location.coordinate.longitude];
        
        [[NSUserDefaults standardUserDefaults] setObject:strLat forKey:@"lat"];
        [[NSUserDefaults standardUserDefaults] setObject:strLon forKey:@"lon"];
        [[NSUserDefaults standardUserDefaults] synchronize];
        
        [[NSNotificationCenter defaultCenter] postNotificationName:@"postUpdateLocationMessage" object:nil];
        [self performCoordinateGeocode:self.location.coordinate
                             success:^(id responseObject) {
                                 NSDictionary *placeCityDic = (NSDictionary *)responseObject;
                                 self.city = [[placeCityDic objectForKey:@"City"] stringByReplacingOccurrencesOfString:@"市" withString:@""];
                                 //self.address = [placeCityDic objectForKey:@"Name"];
                                 [[NSUserDefaults standardUserDefaults] setObject:self.city forKey:@"city"];
                                 [[NSUserDefaults standardUserDefaults] synchronize];
                                 
                                 NSLog(@"city = %@, address = %@,latitude = %f, longitude = %f",self.city, self.address,self.location.coordinate.latitude, self.location.coordinate.longitude);
                             } failure:^(NSError *error) {
                             }];
    }];
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
    //[self alertsInfoAction:[NSString stringWithFormat:@"Location fail: %@ Please check your network and location service.",[error localizedDescription] ]];
    if ([self.delegate respondsToSelector:@selector(locationUpdatedFailed:ErrorMessage:)]) {
        [self.delegate locationUpdatedFailed:error.code ErrorMessage:error.localizedDescription];
    }
    
}
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
    if (status == kCLAuthorizationStatusRestricted || status == kCLAuthorizationStatusDenied) {
        
    }
}

-(void) postUpdateLocationMessage
{
    //{{
    CLLocationCoordinate2D pt = (CLLocationCoordinate2D){0, 0};
    if (self.location != nil) {
        pt = (CLLocationCoordinate2D){self.location.coordinate.latitude , self.location.coordinate.longitude};
    }
    BMKReverseGeoCodeOption *reverseGeocodeSearchOption = [[BMKReverseGeoCodeOption alloc]init];
    reverseGeocodeSearchOption.reverseGeoPoint = pt;
    BOOL flag = [_geocodesearch reverseGeoCode:reverseGeocodeSearchOption];
    if(flag)
    {
        NSLog(@"反geo检索发送成功");
    }
    else
    {
//        NSLog(@"反geo检索发送失败");
    }
    //}}
}

//USING 百度地图反向地理编码
-(void) onGetReverseGeoCodeResult:(BMKGeoCodeSearch *)searcher result:(BMKReverseGeoCodeResult *)result errorCode:(BMKSearchErrorCode)error
{
    BMKPointAnnotation* item = [[BMKPointAnnotation alloc]init];
    item.coordinate = result.location;
    item.title = result.address;
    self.address = result.address;
    
    NSLog(@"address = %@,latitude = %f, longitude = %f",self.address,item.coordinate.latitude, item.coordinate.longitude);
    if ([self.delegate respondsToSelector:@selector(locationUpdated)]) {
        [self.delegate locationUpdated];
    }
    //[self stopGPS];
}

/**
 *在地图View将要启动定位时，会调用此函数
 *@param mapView 地图View
 */
- (void)mapViewWillStartLocatingUser:(BMKMapView *)mapView
{
	NSLog(@"start locate");
}

/**
 *用户方向更新后，会调用此函数
 *@param userLocation 新的用户位置
 */
- (void)didUpdateUserHeading:(BMKUserLocation *)userLocation
{
    [_mapView updateLocationData:userLocation];
//    NSLog(@"heading is %@",userLocation.heading);
}

/**
 *用户位置更新后，会调用此函数
 *@param userLocation 新的用户位置
 */
- (void)didUpdateBMKUserLocation:(BMKUserLocation *)userLocation
{
    //    NSLog(@"didUpdateUserLocation lat %f,long %f",userLocation.location.coordinate.latitude,userLocation.location.coordinate.longitude);
    [_mapView updateLocationData:userLocation];
    
    self.location = userLocation.location;
    //[_locationManager stopUpdatingLocation];
    NSString *strLat = [NSString stringWithFormat:@"%f", self.location.coordinate.latitude];
    NSString *strLon = [NSString stringWithFormat:@"%f", self.location.coordinate.longitude];
    
    [[NSUserDefaults standardUserDefaults] setObject:strLat forKey:@"lat"];
    [[NSUserDefaults standardUserDefaults] setObject:strLon forKey:@"lon"];
    [[NSUserDefaults standardUserDefaults] synchronize];
    
    [[NSNotificationCenter defaultCenter] postNotificationName:@"postUpdateLocationMessage" object:nil];
    [self performCoordinateGeocode:self.location.coordinate
                           success:^(id responseObject) {
                               NSDictionary *placeCityDic = (NSDictionary *)responseObject;
                               self.city = [[placeCityDic objectForKey:@"City"] stringByReplacingOccurrencesOfString:@"市" withString:@""];
                               //self.address = [placeCityDic objectForKey:@"Name"];
                               [[NSUserDefaults standardUserDefaults] setObject:self.city forKey:@"city"];
                               [[NSUserDefaults standardUserDefaults] synchronize];
                               DebugLog(@"address = %@,latitude = %f, longitude = %f",self.address,self.location.coordinate.latitude, self.location.coordinate.longitude);
//                               NSLog(@"address = %@,latitude = %f, longitude = %f",self.address,self.location.coordinate.latitude, self.location.coordinate.longitude);
                           } failure:^(NSError *error) {
                           }];
    
    //{{
    CLLocationCoordinate2D pt = (CLLocationCoordinate2D){0, 0};
    if (self.location != nil) {
        pt = (CLLocationCoordinate2D){userLocation.location.coordinate.latitude , userLocation.location.coordinate.longitude};
    }
    BMKReverseGeoCodeOption *reverseGeocodeSearchOption = [[BMKReverseGeoCodeOption alloc]init];
    reverseGeocodeSearchOption.reverseGeoPoint = pt;
    BOOL flag = [_geocodesearch reverseGeoCode:reverseGeocodeSearchOption];
    if(flag)
    {
        NSLog(@"反geo检索发送成功");
    }
    else
    {
//        NSLog(@"反geo检索发送失败");
    }
    //}}
}

/* 通过用户坐标,获取城市名称 */
- (void)performCoordinateGeocode:(CLLocationCoordinate2D)coordinate success:(void (^)(id))success failure:(void (^)(NSError *))failre
{
    void (^succesd)(id returnObject) = success;
    void (^faild)(NSError *error) = failre;
    
    CLGeocoder *geocoder = [[CLGeocoder alloc] init];
    //    CLLocationCoordinate2D coordinate =  _currentUserCoordinate;
    CLLocation *location = [[CLLocation alloc] initWithLatitude:coordinate.latitude longitude:coordinate.longitude];
    
    [geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
        if (error){
            //            NSLog(@"Geocode failed with error: %@", error);
            dispatch_async(dispatch_get_main_queue(),^ {
                faild(error);
            });
            return;
        }
        
        dispatch_async(dispatch_get_main_queue(),^ {
            //            NSLog(@"Received placemarks: %@", placemarks);
            CLPlacemark *theresult = [placemarks objectAtIndex:0];
            NSDictionary *placeCityDic = theresult.addressDictionary;
            succesd(placeCityDic);
        });
    }];
}

@end
